package cn.hengzhu.main_manager.web.controller;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.*;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import cn.hengzhu.main_manager.repository.domain.*;
import cn.hengzhu.main_manager.repository.param.ManageCaseTypeParam;
import cn.hengzhu.main_manager.repository.vo.ManagerCaseTypePriceVO;
import cn.hengzhu.main_manager.service.ManageCaseTypeService;
import cn.hengzhu.main_manager.utils.*;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import cn.hengzhu.main_manager.repository.dao.ManageCaseMapper;
import cn.hengzhu.main_manager.repository.dao.ManageCaseTypeMapper;
import cn.hengzhu.main_manager.repository.dao.ManageCompMapper;
import cn.hengzhu.main_manager.repository.vo.ManageCaseTypeVO;
import cn.hengzhu.main_manager.service.ManageCaseBoxService;
import cn.hengzhu.main_manager.utils.ann.MoblieUrl;

@Controller
@RequestMapping("/caseType")
public class CaseTypeController {

	private Map<Integer,Map<String, ManageCaseTypePrice>> tsMap = new HashMap<>();

	@Autowired
	private ManageCaseTypeMapper manageCaseTypeMapper;
	@Autowired
	private ManageCaseTypeService manageCaseTypeService;
	@Autowired
	private ManageCompMapper manageCompMapper;
	@Autowired
	private ManageCaseBoxService manageCaseBoxService;
	@Autowired
	private HttpServletRequest request;
	@Autowired
	private ManageCaseMapper manageCaseMapper;

	/**
	 * @author 刘成
	 * @since 2018年8月10日
	 * @return 跳转列表页面
	 */
	@MoblieUrl
	@RequestMapping("/index")
	public String getCaseType(Model model) {
		ManageUser user = UserContext.getUser();
		Integer compId = user.getCompId();
		List<ManageComp> compListBySelect = manageCompMapper.getCompListBySelect(user.getCompId());
		model.addAttribute("comp", compListBySelect);
		model.addAttribute("compId", compId);
		return request.getAttribute("moblie") + "caseType";
	}

	@MoblieUrl
	@RequestMapping("/add")
	public String add(Model model, String typeId) {
		ManageUser user = UserContext.getUser();
		Integer compId = user.getCompId();
		List<ManageComp> compListBySelect = manageCompMapper.getCompListBySelect(user.getCompId());
		model.addAttribute("comps", compListBySelect);
		model.addAttribute("compId", compId);
		model.addAttribute("typeId", typeId);
		return request.getAttribute("moblie") + "caseTypeAdd";
	}




	@MoblieUrl
	@RequestMapping("/caseEdit")
	public String edit(Integer typeId, Model model) {
		ManageUser user = UserContext.getUser();
		List<ManageComp> compListBySelect = manageCompMapper.getCompListBySelect(user.getCompId());

		model.addAttribute("compList", compListBySelect);

		ManageCaseType manageCaseType = manageCaseTypeMapper.selectByPrimaryKey(typeId);
		String priceSize = manageCaseType.getPriceSize();
		if (StringUtils.isNotBlank(priceSize)) {
			String[] split = manageCaseType.getPriceSize().split(",");
			model.addAttribute("priceSize", split);
		}

		model.addAttribute("manageCaseType", manageCaseType);
		return request.getAttribute("moblie") + "caseTypeEdit";
	}

	/**
	 * @author 刘成
	 * @since 2018年8月14日
	 * @param param
	 * @return 列表
	 */
	@ResponseBody
	@RequestMapping("/getCaseTyepList")
	public LayUiResultJson<ManageCaseTypeVO> getCaseTyepList(ManageCaseTypeParam param) {
		ManageUser user = UserContext.getUser();
		Integer compId = user.getCompId();

		List<ManageComp> compListBySelect = manageCompMapper.getCompListBySelect(compId);
		Map<Integer, ManageComp> compMap = compListBySelect.stream()
				.collect(Collectors.toMap(ManageComp::getCompId, v -> v));
		PageHelper.startPage(param.getPage(), param.getLimit(), true);

		if (compId == 0 && param.getCompId() != null && param.getCompId() != -1){
			compId = param.getCompId();
		}

		List<ManageCaseType> caseTypeList = manageCaseTypeMapper.selectTypeByCompId(compId);
		PageInfo<ManageCaseType> pageInfo = new PageInfo<>(caseTypeList);
		List<ManageCaseTypeVO> list = new ArrayList<>();
		caseTypeList.stream().forEach(a -> {
			String priceSize = a.getPriceSize();
			ManageCaseTypeVO manageCaseTypeVO = new ManageCaseTypeVO();
			manageCaseTypeVO.setIsDefault(a.getIsDefault());
			manageCaseTypeVO.setName(a.getName());
			manageCaseTypeVO.setTypeId(a.getTypeId());

			// `PAY_TIME` '收费时间（1.使用后 2.使用前）',
			if (Byte.valueOf("1").equals(a.getPayTime())) {
				manageCaseTypeVO.setPayTime("使用后");
			} else {
				manageCaseTypeVO.setPayTime("使用前");
			}

			ManageComp manageComp = compMap.get(a.getCompId());
			if (manageComp != null) {
				manageCaseTypeVO.setCompName(manageComp.getCompName());
			} else {
				manageCaseTypeVO.setCompName("该公司已被删除");

			}

			// `PAY_TYPE` '收费类型（0，免费 1.计时 2.记次）',
			if (Byte.valueOf("0").equals(a.getPayType())) {
				manageCaseTypeVO.setPayType("免费");
				manageCaseTypeVO.setPrice("免费");
				manageCaseTypeVO.setPriceSize("免费");

			} else if (Byte.valueOf("1").equals(a.getPayType())) {
				manageCaseTypeVO.setPayType("计时");
				manageCaseTypeVO.setPrice(a.getPrice() + "元/" + a.getUserTime() + "小时");
				if (StringUtils.isNotBlank(priceSize) && !priceSize.equals(",,")) {
					manageCaseTypeVO.setPriceSize(priceSize + "元/" + a.getUserTime() + "小时");
				} else {
					manageCaseTypeVO.setPriceSize("没有设置");
				}

			} else if (Byte.valueOf("2").equals(a.getPayType())) {
				manageCaseTypeVO.setPayType("计次");
				manageCaseTypeVO.setPrice(a.getPrice() + "元/次");
				if (StringUtils.isNotBlank(priceSize) && !priceSize.equals(",,")) {
					manageCaseTypeVO.setPriceSize(priceSize + "元/次");
				} else {
					manageCaseTypeVO.setPriceSize("没有设置");
				}
			}
			manageCaseTypeVO.setIsBindMobile(a.getIsBindMobile());// 是否须要绑定手机
			manageCaseTypeVO.setIsHalfwayRestart(a.getIsHalfwayRestart());// 中途取件是否重新计费
			manageCaseTypeVO.setIsMidwayFetch(a.getIsMidwayFetch());
			list.add(manageCaseTypeVO);

		});
		long count = pageInfo.getTotal();
		LayUiResultJson<ManageCaseTypeVO> result = new LayUiResultJson<ManageCaseTypeVO>();
		result.setCount(count);
		result.setData(list);
		return result;
	}

	/**
	 * @author 刘成
	 * @since 2018年8月10日
	 * @param typeId
	 * @return 删除类别名称下的所有收费规则
	 */
	@ResponseBody
	@RequestMapping("/deleteCaseTyep")
	public AjaxResult deleteCaseTyep(Integer typeId) {
		ManageCaseExample manageCaseExample = new ManageCaseExample();
		manageCaseExample.createCriteria().andTypeIdEqualTo(typeId);
		List<ManageCase> manageCaseList = manageCaseMapper.selectByExample(manageCaseExample); // 从柜子列表中查询是否有使用这个收费规则
		if (!manageCaseList.isEmpty()) {
			return new AjaxResult("删除失败,此类型正在被使用！");
		} else {
			try {
//				int deleteByExample = manageCaseTypeMapper.deleteByPrimaryKey(typeId);
				Boolean f = manageCaseTypeService.deleteAllPrimaryKey(typeId);
				if (!f) {
					return new AjaxResult("删除失败");
				} else {
					return new AjaxResult();
				}
			} catch (Exception e) {
				return new AjaxResult("删除失败");
			}

		}

	}

	/**
	 * @author 刘成
	 * @since 2018年8月10日
	 * @param typeId
	 * @return 设为默认
	 */
	@ResponseBody
	@RequestMapping("/setDefault")
	public AjaxResult setDefault(Integer typeId) {
		ManageCaseType manageCaseType = new ManageCaseType();
		manageCaseType.setTypeId(typeId);
		manageCaseType.setIsDefault((byte) 1);
		// 查询所愿类型的公司Id
		ManageCaseType record = manageCaseTypeMapper.selectByPrimaryKey(typeId);
		Integer compId = record.getCompId();
		// 根据所选公司的Id查询有无其他的默认类型
		ManageCaseTypeExample example = new ManageCaseTypeExample();
		example.createCriteria().andCompIdEqualTo(compId).andIsDefaultEqualTo((byte) 1);
		List<ManageCaseType> selectByExample = manageCaseTypeMapper.selectByExample(example);
		if (selectByExample.isEmpty()) {
			try {
				int updateByPrimaryKeySelective = manageCaseTypeMapper.updateByPrimaryKeySelective(manageCaseType);
				if (updateByPrimaryKeySelective == 0) {
					return new AjaxResult("设置失败");
				} else {
					return new AjaxResult();
				}
			} catch (Exception e) {
				return new AjaxResult("设置失败");
			}
		} else {// 有默认的选择
			try {
				ManageCaseType manageCaseType2 = selectByExample.get(0);
				Integer typeId2 = manageCaseType2.getTypeId();
				manageCaseBoxService.setDefaultType(typeId2, manageCaseType);
				return new AjaxResult();
			} catch (Exception e) {
				return new AjaxResult("设置失败");
			}

		}

	}

	/**
	 * @author 刘成
	 * @since 2018年8月10日
	 * @param manageCaseType
	 * @return 添加类型
	 */
	@ResponseBody
	@RequestMapping("/addCaseTyep")
	public AjaxResult addCaseTyep(ManageCaseType manageCaseType) {
		try {

			System.err.println(JSONObject.toJSONString(manageCaseType));
			manageCaseType.setCrateTime(new Date());
			/*if (manageCaseType.getPriceSize().equals(",,")) {
				manageCaseType.setPriceSize("");
			}*/
			ManageCaseTypeExample example = new ManageCaseTypeExample();
			example.createCriteria().andNameEqualTo(manageCaseType.getName())
					.andCompIdEqualTo(manageCaseType.getCompId());
			long count = manageCaseTypeMapper.countByExample(example);
			if (count >= 1) {
				return new AjaxResult("已有此名称");
			}
			int insertSelective = manageCaseTypeMapper.insertSelective(manageCaseType);
			if (insertSelective == 0) {
				return new AjaxResult("添加失败");
			} else {
				return new AjaxResult();
			}
		} catch (Exception e) {
			return new AjaxResult("添加失败");
		}

	}

	@ResponseBody
	@RequestMapping("/editCaseTyep")
	public AjaxResult editCaseTyep(ManageCaseType manageCaseType) {
		ManageCaseTypeExample example = new ManageCaseTypeExample();
		example.createCriteria().andNameEqualTo(manageCaseType.getName()).andCompIdEqualTo(manageCaseType.getCompId());
		List<ManageCaseType> manageCaseTypeList = manageCaseTypeMapper.selectByExample(example);
		if (!manageCaseTypeList.isEmpty()) {
			if (manageCaseTypeList.get(0).getTypeId() != manageCaseType.getTypeId()) {
				return new AjaxResult("已有此名称");
			}
		}
		try {
			manageCaseTypeMapper.updateByPrimaryKeySelective(manageCaseType);
			return new AjaxResult();
		} catch (Exception e) {
			return new AjaxResult("修改失败");
		}

	}

	@ResponseBody
	@RequestMapping("/getCompList")
	public List<ManageComp> getCompList() {
		List<ManageComp> compList = new ArrayList<>();
		ManageUser user = UserContext.getUser();
		Integer compId = user.getCompId();
		List<ManageComp> list = manageCompMapper.getCompListBySelect(compId);
		list.stream().forEach(a -> {
			ManageComp manageComp = new ManageComp();
			manageComp.setCompName(a.getCompName());
			manageComp.setCompId(a.getCompId());
			compList.add(manageComp);
		});

		return compList;
	}

	@ResponseBody
	@RequestMapping("/getPayList")
	public List<ManageCaseType> getPayList(Integer compId) {
		List<ManageCaseType> caseTypeList = manageCaseTypeMapper.selectTypeByCompId(compId);
		ManageCaseType manageCaseType = new ManageCaseType();
		manageCaseType.setTypeId(-1);
		manageCaseType.setName("不选，则为默认类型");
		caseTypeList.add(0, manageCaseType);
		return caseTypeList;
	}


	/**
	 * 4个功能：
	 * 		1. 临时修改 只有id没有typeId则为临时修改
	 * 		2. 数据库中修改 有id 和typeId 参数则为数据库中修改
	 * 		3. 临时保存 id和typeId都没有则为临时保存
	 * 		4. 数据库中保存 没有id 有typeId则为数据库中保存
	 * @param mctp
	 * @return 成功或者失败
	 */
	@ResponseBody
	@RequestMapping("/retain")
	public AjaxResult saveRetain(ManagerCaseTypePriceVO mctp) {
		ManageUser user = UserContext.getUser();
		String typeId = mctp.getTypeId();
		String id = mctp.getId();
		AjaxResult ajaxResult = new AjaxResult();
		if (typeId != null && id != null && id.length() > 0 && typeId.length() > 0 ){ // 去数据库中修改
			int returnEd = manageCaseTypeService.persistentUpdate(mctp,id, typeId);
			ajaxResult.setMessage("修改成功");
			return returnEd != 1 ? new AjaxResult("修改失败！") : ajaxResult;
		}

		Integer userId = user.getManagerId(); // 获得当前登录用户id
		Map<String, ManageCaseTypePrice> temporaryMap = tsMap.get(userId); // 当前登录用户对应的临时收费类型
		if (temporaryMap == null || temporaryMap.isEmpty()){ // 判断这个用户之前是否存储过 没存储则赋值一个新的进去
			Map<String, ManageCaseTypePrice> newMap = new HashMap<>();
			temporaryMap = newMap;
		}

		if (id != null && id.length() > 0){ // 判断是否有id参数， 有则是临时修改
			return this.update(userId, temporaryMap, mctp);
		}

		if ((id == null || id.length() == 0 ) && typeId != null && typeId.length() > 0) { // 保存到数据库中
			int restrnEd = manageCaseTypeService.persistentInsert(mctp, typeId);
			ajaxResult.setMessage("添加成功！");
			return restrnEd == 1 ? ajaxResult : new AjaxResult("添加失败");
		}

		// 临时保存
		ManageCaseTypePrice manageCaseTypePrice = new ManageCaseTypePrice();
		String lId = temporaryMap.size() + 1 + "";  // 临时id
		manageCaseTypePrice.setId(Integer.parseInt(lId));
		Integer theLenght = mctp.getTheLenght(); // 时长
		manageCaseTypePrice.setTheLenght(theLenght);
		String thePrice = mctp.getThePrice();// 价格
		manageCaseTypePrice.setThePrice(AmountUtils.changeY2F(thePrice));
		temporaryMap.put(lId, manageCaseTypePrice); //存入map

		tsMap.put(userId, temporaryMap);

		return new AjaxResult();
	}


	/**
	 * 修改临时收费类型
	 * @param userId 用户登录id
	 * @param temporaryMap 用户对应的临时收费map
	 * @param mctp 要修改的对应的数据
	 * @return
	 */
	private AjaxResult update(Integer userId, Map<String, ManageCaseTypePrice> temporaryMap, ManagerCaseTypePriceVO mctp){

		String id = mctp.getId();
		ManageCaseTypePrice manageCaseTypePrice = temporaryMap.get(id); // 获取id对应列的数据
		manageCaseTypePrice.setThePrice(AmountUtils.changeY2F(mctp.getThePrice()));
		manageCaseTypePrice.setTheLenght(mctp.getTheLenght());
		temporaryMap.put(id, manageCaseTypePrice);

		AjaxResult ajaxResult = new AjaxResult();
		ajaxResult.setMessage("修改成功");
		return ajaxResult;
	}



	@RequestMapping("/addPrice")
	public String addPrice(String id,String typeId, Model model) {

		if (id != null && typeId != null && typeId.length() > 0){
			// 点击了修改按钮 数据从数据库中查询
			ManageCaseTypePriceExample example = new ManageCaseTypePriceExample();
			example.createCriteria().andIdEqualTo(Integer.valueOf(id));
			List<ManageCaseTypePrice> list =  manageCaseTypeService.selectByExample(example);
			ManageCaseTypePrice manageCaseTypePrice = list.get(0);
			model.addAttribute("id", id);
			model.addAttribute("typeId", typeId);
			model.addAttribute("data", manageCaseTypePrice);
			return "caseTypeAdd1";
		}

		// 是否有id 有则是点击的修改按钮 从临时map中查询
		if(id != null) {
			ManageUser user = UserContext.getUser();
			Integer userId = user.getManagerId();
			Map<String, ManageCaseTypePrice> stringManagerCaseTypePriceMap = tsMap.get(userId);
			ManageCaseTypePrice manageCaseTypePrice = stringManagerCaseTypePriceMap.get(id);
			ManageCaseTypePrice copyManageCaseTypePrice = SerializationUtils.clone(manageCaseTypePrice);
			try {
				copyManageCaseTypePrice.setThePrice(AmountUtils.changeF2Y(manageCaseTypePrice.getThePrice()));
			} catch (Exception e) {
				e.printStackTrace();
			}
			model.addAttribute("id", id);
			model.addAttribute("data", copyManageCaseTypePrice);
		}
		model.addAttribute("typeId", typeId);
		return "caseTypeAdd1";
	}




	/**
	 * 临时收费数据列表 + 数据库中收费数据列表
	 * @return
	 */
	@GetMapping("/list")
	@ResponseBody
	public LayUiResultJson<ManageCaseTypePrice> getList(Integer typeId) {
		ManageUser user = UserContext.getUser();
		Integer userId = user.getManagerId();

		if (typeId != null ){
			// 从数据库中查询数据
			ManageCaseTypePriceExample example = new ManageCaseTypePriceExample();
			example.createCriteria().andCaseTypeIdEqualTo(typeId);
			List<ManageCaseTypePrice> list =  manageCaseTypeService.selectByExample(example);
			return new LayUiResultJson<>(0,list);
		}

		Map<String, ManageCaseTypePrice> temporaryMap = tsMap.get(userId);
		if (temporaryMap == null || temporaryMap.size() == 0){
			return new LayUiResultJson<>(0,null);
		}
		List<ManageCaseTypePrice> resultList = new ArrayList(temporaryMap.values());
		resultList = depCopy(resultList);

		for (ManageCaseTypePrice manageCaseTypePrice : resultList) {
			String thePrice = manageCaseTypePrice.getThePrice();
			try {
				manageCaseTypePrice.setThePrice(AmountUtils.changeF2Y(thePrice));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return new LayUiResultJson<>(0,resultList);
	}


	/**
	 * 深拷贝list
	 * @param srcList
	 * @param <T>
	 * @return
	 */
	public static <T> List<T> depCopy(List<T> srcList) {
		ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
		try {
			ObjectOutputStream out = new ObjectOutputStream(byteOut);
			out.writeObject(srcList);

			ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
			ObjectInputStream inStream = new ObjectInputStream(byteIn);
			List<T> destList = (List<T>) inStream.readObject();
			return destList;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}





	/**
	 * 只要有typeId， 那么都是从数据库中操作
	 * 删除临时收费类型
	 * @param id 要删除的id
	 * @return
	 */
	@GetMapping("/del")
	@ResponseBody
	public AjaxResult del(String id, String typeId){
		ManageUser user = UserContext.getUser();
		Integer userId = user.getManagerId();


		if (typeId != null && id != null && typeId.length() > 0){
			int result = manageCaseTypeService.persistentDel(id, typeId);
			AjaxResult ajaxResult = new AjaxResult();
			ajaxResult.setMessage("删除成功");
			return result == 1 ? ajaxResult : new AjaxResult("删除失败");
		}

		Map<String, ManageCaseTypePrice> managerCaseTypePriceMap = tsMap.get(userId);
		managerCaseTypePriceMap.remove(id);
		AjaxResult ajaxResult = new AjaxResult();
		ajaxResult.setMessage("删除成功");
		return ajaxResult;
	}


	/**
	 * 立即提交，保存到数据库中
	 * @param manageCaseType
	 * @return
	 */
	@PostMapping("/persistentsave")
	@ResponseBody
	public AjaxResult persistentSave(ManageCaseType manageCaseType){
		ManageUser user = UserContext.getUser();
		Integer userId = user.getManagerId();
		Map<String, ManageCaseTypePrice> managerCaseTypePriceMap = tsMap.get(userId);
		Boolean tag = manageCaseTypeService.persistentSave(manageCaseType, managerCaseTypePriceMap);
		if (!tag){
			return new AjaxResult("提交失败");
		}
		tsMap.clear(); // 清空临时数据
		AjaxResult ajaxResult = new AjaxResult();
		ajaxResult.setMessage("提交成功");
		return ajaxResult;
	}

}
